/*
 * File:   928.cpp
 * Author: xerxes
 *
 * Created on September 16, 2011, 8:39 AM
 *
 * I have not failed, I have just found 10000 ways that won't work.
 */

#include <iostream>
#include <algorithm>
#include <vector>
#include <sstream>
#include <fstream>
#include <string>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <functional>
#include <bitset>
#include <iomanip>

#include <ctime>
#include <cassert>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <climits>
#include <cstring>
#include <cstdlib>

using namespace std;

#define VI vector< int >
#define CI( x ) scanf("%d",&x)
#define CL( x ) scanf("%lld",&x)
#define CD( x ) scanf("%lf",&x )
#define fo(i,st,ed) for(int i = st ; i < ed ; ++i )
#define foE(i,st,ed) for(int i = st ; i <= ed ; ++i )
#define foit(i, x) for (typeof((x).begin()) i = (x).begin(); i != (x).end(); i++)
#define bip system("pause")
#define Int long long
#define pb push_back
#define SZ(X) (int)(X).size()
#define LN(X) (int)(X).length()
#define mk make_pair
#define f first
#define s second
#define SET( ARRAY , VALUE ) memset( ARRAY , VALUE , sizeof(ARRAY) )

inline void wait(double seconds) {
    double endtime = clock()+(seconds * CLOCKS_PER_SEC);
    while (clock() < endtime) {
        ;
    }
}

int R, C;
char grid[310][310];
int cost[310][310][4];

inline void Read() {
    CI(R);
    CI(C);
    getchar();

    fo(i, 0, R) {

        fo(j, 0, C) {
            grid[i][j] = getchar();
            cost[i][j][1] = cost[i][j][2] = cost[i][j][3] = (int) 1023456789;
        }
        getchar();
    }
}

inline void Print() {

    fo(i, 0, R) {

        fo(j, 0, C) {
            cout << grid[i][j] << " ";
        }
        cout << "\n";
    }
    cout << "\n\n";
}

struct NODE {
    int r, c, m;

    NODE(int _r, int _c, int _m) :
    r(_r), c(_c), m(_m) {
        ;
    }
};

inline void _Find(int &r, int &c, char ss) {

    fo(i, 0, R) {

        fo(j, 0, C) {
            if (ss == grid[i][j]) {
                r = i;
                c = j;
                return;
            }
        }
    }
}
int _r[] = {-1, +1, +0, +0};
int _c[] = {+0, +0, -1, +1};

inline void Proc() {
    int sr, sc, dr, dc;
    _Find(sr, sc, 'S');
    _Find(dr, dc, 'E');

    queue< NODE > q;
    q.push(NODE(sr, sc, 1));
    cost[sr][sc][1] = 0;

    while (q.empty() == false) {
        NODE t = q.front();
        q.pop();
        int r=t.r;
        int c=t.c;
        int nw_mood=t.m;
        int nxt_mood = (t.m+1)%3 ==0 ? 3 : (t.m+1)%3;
        int pcost=cost[r][c][nw_mood];

        fo(i,0,4){
            int good=true;
            foE(k,1,nw_mood){
                int tr = r+ (_r[i]*k);
                int tc = c+ (_c[i]*k);
                if( tr<0 || tc<0 || tr>=R || tc>=C ){
                    good=false;
                }
                if( grid[tr][tc]=='#' ){
                    good=false;
                }
            }
            if(good){
                int nwr = r+(_r[i]*nw_mood);
                int nwc = c+(_c[i]*nw_mood);
                if( pcost+1 < cost[nwr][nwc][ nxt_mood] ){
                    cost[nwr][nwc][ nxt_mood] = pcost+1;
                    q.push( NODE(nwr,nwc,nxt_mood) );
                }
            }
        }

    }

    int a = cost[dr][dc][1];
    int b = cost[dr][dc][2];
    int c = cost[dr][dc][3];
    int d = min(a, min(b, c));
    if (d < (int) 1023456789) {
        printf("%d\n", d);
    } else {
        printf("NO\n");
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in", "rt", stdin);
#endif

    int cases = 1;
    for (CI(cases); cases; --cases) {
        Read();
        Proc();
    }

    return 0;
}


